iT邦幫忙

2026 iThome 鐵人賽

DAY 21
0

📦 不一定。以 Claude Code 為例,開了 sandbox 之後 Bash 只能寫專案目錄、連不到沒允許的網址,但家目錄的憑證檔和環境變數裡的密鑰照樣讀得到;要另外擋讀取、拿掉環境變數裡的密鑰、設定 sandbox 起不來就停,再實際跑一次確認。

昨天在 Day 20|寫在 Prompt 裡的規則,擋得住 Agent 嗎?,我們看了 gemini-cli 的 Issue 分類 workflow:prompt 裡的守則擋不住,要把 token 拿出模型那一步,寫回交給模型外的程式;用 Claude Code 的話,規則寫進權限設定,要擋檔案和網路就開 sandbox。今天接著看:sandbox 是什麼,開了到底擋住了什麼?

快速回顧一下:Day 20 提過,Claude Code 的權限規則 Read(./.env) 擋得住 cat,擋不住一支自己去開檔案的 Python 腳本,因為規則比對的是工具呼叫寫了什麼;sandbox 換成由作業系統來擋,管的是 Bash 和它啟動的 subprocess。

2025 年 9 月,npm 上出現一隻叫 Shai-Hulud 的蠕蟲。被植入的套件在安裝時跑一段 postinstall 腳本(npm 裝完套件會自動執行的指令),把環境變數整份倒出來,用 TruffleHog 掃檔案找金鑰,再把結果送到 webhook.site 和一個新建的公開 GitHub repo;接著用偷到的 npm token,把自己發到那位維護者的其他套件裡(StepSecurity 的分析)。

假設你在 Claude Code 裡請它幫忙裝依賴、跑測試,而且已經用 /sandbox 開了 sandbox。依賴裡只要有一個被植入的套件,那段安裝腳本就會在 sandbox 裡跑。它碰得到什麼?我照 Shai-Hulud 會做的事挑了五個動作,用假的憑證檔和假的環境變數,請 Claude Code 在 sandbox 裡一個一個跑。

開著預設的 sandbox,家目錄裡的假憑證,cat 讀得到,Python 也讀得到;環境變數裡的假 token 印得出來。寫家目錄和連外面的網址,都被擋下來。

開了 sandbox,讀得到憑證、寫不出也連不出

圖:左邊是 Shai-Hulud 這類安裝腳本會做的事 → 中間是 Claude Code 預設 sandbox 的實測結果,讀家目錄的假憑證、印環境變數都成功,寫家目錄和連 example.com 被擋 → 右邊是 sandbox 管不到的地方:Claude 內建的讀檔工具、hooks、MCP server、你自己打的 ! 指令、excludedCommands、不開 sandbox 的重跑,還有 sandbox 起不來時照常執行。這是示意,實作要照自己的工具和環境調整。

sandbox 擋住了寫和連外,讀和環境變數沒擋。下面先講 sandbox 是什麼、各家怎麼用、底下靠什麼做到,再把實驗的設定和改前改後的結果並排,接著看還有哪些東西本來就在 sandbox 外面,最後落成啟動 sandbox 時最少要做的檢查。

Sandbox 是什麼,拿來做什麼?

sandbox 指的是把一段程式關在劃好範圍的環境裡跑:它能讀寫哪些檔案、能連哪些網址,由環境外面的東西決定,程式自己改不了。範圍畫在哪一層,常見的做法有三種:用作業系統的機制限制單一個 process、放進 container、放進有自己 kernel 的 VM,後面「底下靠什麼做到」那節會分開講。

Claude Code 在你電腦上的 sandbox 用的是第一種。開了之後,模型提出的 Bash 指令不會直接交給 shell 跑。Claude Code 先用作業系統提供的機制,替這次要啟動的 shell 套上一份規則:哪些路徑能讀、哪些能寫、網路只能連到哪裡。規則套在 process 上,它啟動的 subprocess 全部跟著繼承。之後 process 每次開檔、寫檔、連線,都由作業系統照規則檢查,不在範圍內就失敗。

所以 sandbox 不看指令怎麼寫。cat 讀檔和 Python 自己開檔,在作業系統那一層都是同一個開檔動作。這是它跟 Day 20 的權限規則差最多的地方,兩個並排看:

權限規則 Claude Code 的 sandbox
誰檢查 Claude Code,在工具執行之前 作業系統,在 process 開檔、寫檔、連線的時候
看什麼 工具呼叫寫了什麼:指令文字、路徑參數 process 實際要碰的檔案和網址
管到哪些工具 全部,包括內建的 Read、Edit、WebFetch 和 MCP 工具 只有 Bash 指令和它啟動的 subprocess
擋不住 換一種寫法,例如 grep -r、自己開檔的 Python 不經過 Bash 的東西:內建工具、hooks、MCP server

兩樣要一起用:權限規則決定哪些工具呼叫要先問你,sandbox 限制 Bash 指令跑起來之後碰得到什麼。

Anthropic 介紹 Claude Code sandbox 的文章講了兩個用途。第一個是防 prompt injection(藏在網頁、Issue 這類外部內容裡、想讓模型照著做的指示):模型就算被騙了,檔案隔離讓它改不到系統上的敏感檔案,網路隔離讓它送不出資料、也下載不了惡意程式。文章也講了為什麼兩樣都要開:少了網路隔離,被騙的 Agent 可以把 SSH key 這類檔案送出去;少了檔案隔離,它很容易就逃出 sandbox、拿到網路。

第二個用途是少問你幾次。範圍內的指令可以直接跑,不用每個都等你按同意;Anthropic 說他們內部使用時,跳出來要你確認的次數少了 84%。

Claude Code 的 sandbox 預設是關的,要用 /sandbox 或在設定裡寫 sandbox.enabled: true 打開。

各家怎麼用?

上一節是照隔離做在哪一層來分;換成照「關進去的是什麼」來分,各家的用法有兩種:一種只把 Agent 執行的指令關起來,Agent 本身還是跑在你的電腦上;另一種把整個 Agent 放進 container 或 VM。本機的 coding agent 多半是前一種,雲端版本是後一種。

Claude Code 兩種都有。在你電腦上跑的,就是上一節的 sandbox,只包 shell 指令;網頁版的 Claude Code 每個 session 跑在 Anthropic 管理的 VM 裡,git 的憑證不放進 VM,由 VM 外面的 proxy 在送出時附上。Claude Code 的執行環境比較也寫了,只開 Bash 的 sandbox 不夠讓 Agent 完全沒人看著跑;要用 --dangerously-skip-permissions 跳過所有確認,就放進 container、VM,或 Anthropic 開源的 sandbox-runtime(把 Claude Code 用的同一套限制拿來包整個程式)裡。

其他幾家各一句:

  • Codex CLI 分三種模式:只能讀、能寫工作目錄、完全不限制。建議的組合是能寫工作目錄,超出範圍時再問你;這個模式下網路預設關閉,可寫的資料夾裡 .git 和 .codex 還是受保護。Codex 的雲端版本跑在 OpenAI 管理的 container 裡,裝環境的階段可以上網,Agent 開始工作後預設離線。
  • Gemini CLI 的 sandbox 預設關閉,用 --yolo(全部自動同意)時才預設打開。macOS 上的預設規則只把寫入限制在專案目錄,讀檔和網路都放寬;也可以改成整個跑在 Docker、Podman 或 gVisor 裡。
  • Cursor 的 Agent 跑 shell 指令時,讀寫限在工作區,.git/config、.git/hooks、.vscode 另外保護;網路先全擋,再照你的允許清單和 Cursor 內建的套件管理器網域打開。放不進 sandbox 的指令,交給另一個模型判斷要不要放行。雲端的 Agent 各自跑在一台專用的機器上。
  • OpenHands 把執行方式分成同機 process、Docker 和遠端,直接寫同機 process 沒有 container 等級的隔離;用 Docker 的話,整個 Agent 的服務跑在 container 裡。

放在一起看,寫入範圍和網路各家都收,讀這一塊 Claude Code 和 Gemini CLI 的預設都放得很寬,家目錄讀得到。OpenAI 談內部 Codex 部署的文章把可寫範圍、受保護路徑和網路政策分開管理,不認識的網域進核准流程,憑證放在作業系統的 Keyring。這是他們自己的部署方式,我會借的是那個拆法:讀、寫、網路、憑證,自己的設定裡各設到哪裡,一項一項看。

Sandbox 底下靠什麼做到?

一個 Bash 指令在 Claude Code 的 sandbox 裡是這樣走的:

模型提出一個 Bash 指令
  → Claude Code 套上規則,再啟動 shell
      macOS:Seatbelt(sandbox-exec 帶一份規則檔)
      Linux:bubblewrap(給 process 自己的檔案系統視角和網路)
  → 指令和它的 subprocess 開檔、寫檔
      → 作業系統照規則檢查,不在範圍內:Operation not permitted
  → 指令要連網路
      → 只通得到 sandbox 外面的 proxy
      → proxy 比對網域清單,不在清單上:403

macOS 上用的是 Seatbelt,macOS 內建的 process 限制機制:用 sandbox-exec 啟動程式時帶一份規則檔,寫明哪些路徑能讀寫、能不能連網路。Claude Code 背後的 sandbox-runtime 每次照設定產生這份規則檔;Codex、Cursor、Gemini CLI 在 macOS 上也都是用 Seatbelt。

Linux 上 Claude Code 和 Codex 預設用 bubblewrap。它用的是 Linux 的 namespace,這個功能可以讓一個 process 看到另一套檔案目錄和網路設定:bubblewrap 只把允許的目錄放進那套檔案目錄,網路那一份則是空的,沒有能連到外面的網卡。Cursor 在 Linux 上改用 kernel 內建的 Landlock 限制檔案存取,再用 seccomp 擋掉特定的 system call(程式向作業系統要求開檔、連線這類動作的入口)。

網路那一段,sandbox 裡的指令沒有直接對外的路,只連得到 sandbox 外面的一個 proxy(Claude Code 透過 Unix socket 接過去)。proxy 看每個連線要去的網域,在清單上才放行。下一節實驗裡的 Operation not permitted 和 403,就是這兩道檢查各擋下來的。proxy 預設只看網域名稱、不看加密連線的內容,文件也提醒這可能被 domain fronting 繞過,也就是連線表面上寫允許的網域,實際送到別的主機。

把整個 Agent 關起來的那一種,差在跟主機共用多少:

做法 跟主機共用什麼 例子
container 同一個 kernel,靠上面講的 namespace 分開 OpenHands 的 Docker sandbox、Gemini CLI 的 Docker 選項、Codex 雲端
gVisor 另外跑一個用一般程式寫成的 kernel,裡面的程式發出的 system call 先被它接住,不直接送到主機的 kernel Gemini CLI 的 runsc 選項
microVM、VM 各有自己的 kernel,靠 hypervisor(管虛擬機的那一層)分開 E2B 每個 sandbox 一台 Firecracker microVM、Docker Sandboxes、網頁版 Claude Code

差別在 kernel。container 裡的程式跟主機用同一個 kernel,kernel 一旦有漏洞,裡面的程式就有機會碰到主機;gVisor 和 VM 多隔了一層,裡面的程式碰不到主機的 kernel。越往下隔得越開,代價是比較吃資源。

不管哪一層,你把主機上的資料夾接進去(也就是掛載),裡面的程式就看得到:OpenHands 的 Docker 設定可以用 SANDBOX_VOLUMES 把主機路徑掛進 container,掛成可寫,Agent 就改得動。掛進去的每一個路徑,都要用下一節的五個指令問一次。

開了 sandbox,實際擋住了什麼?

實驗環境是 macOS、Claude Code 2.1.285,模型是 Claude Opus 5.5。家目錄放一個仿 AWS 憑證檔的假檔案 ~/.day21-fake-credentials,啟動 Claude Code 時帶一個假的環境變數 DAY21_FAKE_TOKEN=fake-day21-token。用 claude -p 交代它照順序執行五個指令,每個指令單獨呼叫一次 Bash,指令照抄,被擋就記下錯誤、不要改寫,也不要要求在 sandbox 外重跑。

設定分兩份,放在兩個空資料夾的專案設定裡。一份只寫 "sandbox": { "enabled": true },另一份收緊:

{
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true,
    "allowUnsandboxedCommands": false,
    "filesystem": {
      "denyRead": ["~/"],
      "allowRead": ["."]
    },
    "credentials": {
      "envVars": [
        { "name": "DAY21_FAKE_TOKEN", "mode": "deny" }
      ]
    }
  }
}

四個設定各管一件事,寫法都照文件:

  • denyRead 加 allowRead:擋掉整個家目錄的讀取,只留專案目錄。. 放在專案設定裡才會解析成專案根目錄。
  • credentials.envVars 的 deny:每個 sandbox 裡的指令執行前,先把這個環境變數拿掉。文件也寫了,沒有內建的憑證清單,沒列出來的不會被保護。
  • allowUnsandboxedCommands: false:關掉「在 sandbox 裡失敗,就請你同意改在外面重跑」這條路。
  • failIfUnavailable: true:sandbox 起不來的時候,Claude Code 直接停,不改用沒隔離的方式跑。
指令 想模擬的事 只開 sandbox 收緊後
cat ~/.day21-fake-credentials 掃家目錄的憑證檔 印出整份內容 aws_secret_access_key = fake-day21-secret-not-a-real-key cat: ...: Operation not permitted
python3 -c "...open('~/.day21-fake-credentials')..." 安裝腳本自己開檔 同上,讀到整份內容 PermissionError: [Errno 1] Operation not permitted
echo "token=$DAY21_FAKE_TOKEN" 倒出環境變數 token=fake-day21-token token=
touch ~/sandbox-probe-day21 改家目錄的檔案 Operation not permitted Operation not permitted
curl ... https://example.com 送到外部網址 CONNECT tunnel failed, response 403 同左

只開 sandbox 的設定跑了 2 次,兩次的工具呼叫和輸出完全一樣。收緊的設定也跑了 2 次,第 2 次模型那一輪回覆被 Opus 5.5 自己的安全檢查攔下,五個指令都沒跑,表上是第 1 次的結果。

只開 sandbox 的結果,跟 Claude Code 的 sandbox 文件列的預設對得上:寫只限專案目錄、暫存目錄和另外加進來的目錄;讀是「機器上大部分地方,包括 ~/.ssh 和 ~/.aws/credentials 這類憑證檔」;環境變數從 Claude Code 繼承,「包括裡面的任何密鑰」;網路的允許清單一開始是空的。

放回 Shai-Hulud:改家目錄的檔案會失敗,送到 webhook.site 也會被 proxy 擋下,但它要偷的東西,環境變數和家目錄的憑證檔,都已經拿在手上了。允許清單也不會一直空著:要裝依賴,就得放行 npm 的套件庫 registry.npmjs.org,而 Shai-Hulud 拿偷到的 token 發布新版本,連的也是這個網域。文件對 github.com 有同樣的警告,加進清單可能變成外送的路,Shai-Hulud 偏偏就是把偷到的東西放進一個公開的 GitHub repo。

還有哪些東西本來就在 sandbox 外面?

sandbox 只包 shell 指令和它們啟動的 process。下表前三列會讓指令整個跑到 sandbox 外面,安裝腳本也跟著出去;第四列是放進來的東西本身權限太大;後三列從頭就不經過 Bash:

情況 結果
指令符合 excludedCommands 整個在 sandbox 外跑,例如把 docker * 排除,等於 docker 能做的事都放行
指令在 sandbox 裡失敗 Claude 可以要求不開 sandbox 重跑;一般模式會先問你,bypassPermissions(跳過所有確認)模式不問
sandbox 起不來,例如 Linux 少了 bubblewrap 預設照常執行、不隔離;設了 failIfUnavailable 才會停
允許了 /var/run/docker.sock 這類 Unix socket 文件的例子:等於拿到整台主機
Claude 用內建的 Read、Edit、WebFetch 工具 不經過 sandbox,照權限規則走;denyRead 擋不住 Read 工具,要另外寫 Day 20 那種 Read(...) 規則
hooks、本機的 MCP server、狀態列指令 用你完整的權限執行
你在 ! 後面自己打的指令 多數情況不在 sandbox 裡,所以自己打的指令測不出 sandbox 有沒有作用

Docker socket 那一列的原因,Docker 的文件講得很直接:能對 Docker daemon 下指令,就可能拿到主機的 root 權限。sandbox 擋得住檔案和網路,擋不住一個被你放進來、本身權限就很高的服務。

文件在限制那一節也寫了,sandbox 會降低風險,但不是完整的隔離邊界。要把上面這些都關進同一個邊界,就是前面講的另一種做法:把整個 Claude Code 放進 container 或 VM 裡跑。

啟動 sandbox 時,最少要檢查什麼?

今天的實驗本身就是最小的檢查:sandbox 啟動之後、交給 Agent 之前,先跑幾個「要被擋下來」的動作,有一個沒擋住就不開始。

欄位 這個情境的值或用途 誰讀寫
config 收緊後那份設定:擋家目錄讀取、拿掉 DAY21_FAKE_TOKEN 維運的人寫,launcher(Harness 裡負責把執行環境開起來的那段程式)讀
probes 讀家目錄的假憑證、印受保護的環境變數、寫家目錄、連沒允許的網址,每一項都要失敗 維運的人寫,launcher 啟動後執行
sandbox_id 這次執行環境的編號 寫進 Run 紀錄,結束時用來清理
def start_sandbox(config, probes, launch, run_probe):
    sandbox = launch(config)
    if sandbox is None:
        return {"status": "blocked", "reason": "sandbox_unavailable"}
    leaked = [p.name for p in probes if run_probe(sandbox, p) == "allowed"]
    if leaked:
        sandbox.destroy()
        return {"status": "blocked", "reason": leaked}
    return {"status": "ready", "sandbox_id": sandbox.id}
誰呼叫 什麼時候 結果
Harness 的 launcher 每次要交給 Agent 跑指令之前 四個 probe 都被擋,回 ready
同一個 launcher sandbox 起不來,例如少了 bubblewrap 回 blocked,不改用沒隔離的方式跑
同一個 launcher 讀家目錄的 probe 讀到了內容,像今天的預設設定 銷毀環境、回 blocked,列出漏掉的項目

收緊設定,起不來就停

圖:左邊是改前、改後同樣五個指令的實測輸出,改前讀得到假憑證和假 token,改後五個都被擋 → 右邊是收緊的四個設定各管什麼 → 下方是 launcher 的檢查:sandbox 起不來就停,probe 有一項沒擋住就銷毀環境,都擋住才交給 Agent。這是示意,實作要照自己的工具和環境調整。

可以先從哪裡做起?

假設你從 Day 1 開始自己刻 Harness,已經做到 Day 20:會寫回外部服務的動作,已經搬到模型外面。這時模型提出的 shell 指令,多半是 Harness 直接開一個 subprocess 去跑,用的是你自己的帳號和權限。下一步是在這一行外面包一層 sandbox。

第一步,把執行指令的那一行換成包過的版本。 Seatbelt 規則檔和 bubblewrap 參數不用自己從頭寫。Anthropic 把 Claude Code 用的那一套開源成 sandbox-runtime,可以當指令列工具 srt 用,也可以當函式庫:Harness 啟動時呼叫 SandboxManager.initialize(config) 把網路 proxy 起起來,每次要跑指令就用 wrapWithSandbox(cmd) 拿到包好的指令再執行。被擋下的動作可以用 annotateStderrWithSandboxFailures 標進錯誤輸出,README 建議把工具呼叫的 ID 一起帶進去,模型和 log 都看得出是哪一次呼叫被擋。它還標著 research preview,設定格式可能會變。想看 Codex 的規則會怎麼處理某個指令,可以用 codex sandbox -- <指令> 直接試。

第二步,照讀、寫、網路、憑證四樣訂規則,拿 Codex 的預設當起點。 Codex 在 macOS 上的規則檔開頭就是全部拒絕,再一條一條打開;Linux 上先把整個檔案系統掛成唯讀,只把工作目錄掛成可寫,再把工作目錄裡的 .git、.codex 重新掛回唯讀;網路預設關閉。.git 要另外擋,是因為 .git/hooks 裡的腳本會在你下次 commit 時自動執行,那時已經不在 sandbox 裡,Agent 只要能改它,就等於留了一段之後在外面跑的程式。換成 sandbox-runtime 的設定,就是 allowWrite 只放工作目錄、denyWrite 放 .git、denyRead 擋家目錄,allowedDomains 從空的開始加,文件寫明空清單等於不能連網。

憑證要另外處理,sandbox 擋得住讀檔,擋不住你自己傳進去的環境變數。啟動 subprocess 時只傳指令需要的環境變數,密鑰不放進去。真的要帶憑證連外的,例如 git push,可以學 Cloudflare 的做法和 Docker Sandboxes:sandbox 裡只放一個假的值,請求離開 sandbox 之後,由外面的 proxy 換成真的憑證,Agent 從頭到尾拿不到。網頁版 Claude Code 的 git 也是這樣,真的 token 由 proxy 附上。

第三步,啟動時先檢查,起不來就停。 上一節的 start_sandbox 就是這一步。OpenAI 在 Codex Windows sandbox 的設計文章寫過一次失敗:第一版只靠環境變數叫程式走 proxy 來擋網路,他們自己形容這種保護只是「advisory」,不理會那些變數的程式照樣連得出去,最後改成給 sandbox 專屬的使用者帳號,再用防火牆規則擋。所以檢查用的指令要故意不照規矩走,例如 curl --noproxy '*' 不理會 proxy 設定直接連,才測得出這種漏洞。

第四步,要跑別人的程式碼,就換成每個任務一台用完就丟的 microVM。 跑陌生的 repo、多人共用,或 Harness 本身就在雲端,與其在本機一層一層補,不如每個任務開一台新的:E2B、Vercel Sandbox、Cloudflare Sandbox SDK 都是有自己 kernel 的 microVM;Modal 預設用 gVisor;自己有 Kubernetes 的,Agent Sandbox 讓你像建一個 Kubernetes 資源那樣開 sandbox,底層的隔離交給 gVisor 或 Kata Containers。換了這一層,第二步的問題還是要回答:掛進去哪些路徑、網路開到哪、憑證放不放進去。

用 Claude Code 的話,包指令和網路 proxy 它都做好了,要自己做的是把規則收緊、把退路關掉:用 denyRead 或 credentials 把家目錄和密鑰收起來(內建的 Read 工具另外照 Day 20 寫 Read(...) 規則),設 allowUnsandboxedCommands: false 和 failIfUnavailable: true(/sandbox 的 Overrides 分頁叫 Strict sandbox mode),再請 Claude 跑一次今天的五個指令確認。不要自己在 ! 後面打,自己打的多半不在 sandbox 裡。

只在自己的機器上改自己的專案,做到第二步就能擋掉 Shai-Hulud 這類腳本最想拿的東西;要跑陌生的 repo、在 CI 或多人共用的機器上跑,再做第四步。Day 22 看 Agent 做事時該用誰的身分、拿什麼憑證,Day 24 再看不可信的內容怎麼走到資料出口。

你可以怎麼確認自己讀懂了?

回到裝依賴的那個例子,可以試著問自己:開了 sandbox,安裝腳本讀得到家目錄的憑證檔嗎?如果這台機器的 sandbox 根本起不來,Claude Code 會怎樣?

第一題,預設讀得到。實測用 cat 和 Python 都讀到假憑證的整份內容,環境變數裡的假 token 也印得出來;要加 denyRead 或 credentials 才擋得住。第二題,預設照常執行、不隔離;設了 failIfUnavailable 才會停下來。不一定。以 Claude Code 為例,開了 sandbox 之後 Bash 只能寫專案目錄、連不到沒允許的網址,但家目錄的憑證檔和環境變數裡的密鑰照樣讀得到;要另外擋讀取、拿掉環境變數裡的密鑰、設定 sandbox 起不來就停,再實際跑一次確認。

昨天我們把寫回外部的動作搬出模型那一步,今天把模型那一步讀得到的東西收起來。接下來還有另一個問題:Agent 總要用某個身分去呼叫外部服務,它手上那把憑證,能開的門會不會太多、有效期會不會太久?

參考資料

  1. StepSecurity|Shai-Hulud: Self-Replicating Worm Compromises 500+ NPM Packages:2025-09-15;postinstall 腳本倒出整份環境變數、用 TruffleHog 掃檔案,送到 webhook.site 和新建的公開 GitHub repo,再用偷到的 npm token 發到其他套件。
  2. Anthropic|Beyond permission prompts: making Claude Code more secure and autonomous:2025-10-20;sandbox 的兩個用途(被 prompt injection 騙了也改不到敏感檔案、送不出資料;權限確認少 84%)、檔案和網路隔離為什麼要一起開、網路經過 sandbox 外的 proxy、網頁版的 git 由 proxy 附上真的 token。84% 是 Anthropic 內部使用的數字。
  3. Claude Code|Configure the sandboxed Bash tool:sandbox 預設關閉、macOS 用 Seatbelt 和 Linux 用 bubblewrap、預設讀寫範圍、環境變數、網路 proxy 和允許清單、domain fronting 的提醒、denyRead/credentials 的寫法、allowUnsandboxedCommands、failIfUnavailable、在 sandbox 外面的工具和指令,以及 github.com、Docker socket 的限制說明。實驗結果是我在 macOS、Claude Code 2.1.285 上跑的,換平台要自己重測。
  4. Claude Code|Claude Code on the web:網頁版每個 session 跑在 Anthropic 管理的 VM 裡,git 憑證留在 VM 外由 proxy 附上。
  5. Claude Code|Sandbox environments:只開 Bash 的 sandbox 不夠讓 Agent 完全沒人看著跑,跳過所有確認時要放進 container、VM 或 sandbox-runtime。
  6. OpenAI|Codex: Agent approvals & security:Codex 的三種 sandbox 模式、建議的組合、能寫工作目錄時網路預設關閉、.git 和 .codex 受保護、macOS 用 Seatbelt、雲端版跑在 container 裡。
  7. Gemini CLI|Sandboxing:macOS 的預設規則限制寫入、放寬讀檔和網路,以及 Docker、Podman、gVisor 的選項。
  8. Gemini CLI|Configuration:sandbox 預設關閉,用 --yolo 時預設打開。
  9. Cursor|Run modes:Agent shell 指令的讀寫範圍、受保護路徑、網路允許清單、macOS 用 Seatbelt、Linux 用 Landlock 和 seccomp、放不進 sandbox 的指令交給另一個模型判斷、雲端 Agent 跑在專用機器上。
  10. OpenHands|Sandbox Overview:同機 process、Docker 和遠端三種執行方式,同機 process 沒有 container 等級的隔離。
  11. OpenAI|Running Codex safely at OpenAI:OpenAI 內部 Codex 部署裡可寫範圍、受保護路徑、網路政策和 Keyring 的分工,屬於他們自己的部署方式。
  12. Anthropic|sandbox-runtime:Claude Code 背後的 sandbox 實作,macOS 每次產生 Seatbelt 規則檔,Linux 用 bubblewrap 加 network namespace,網路經過 HTTP 和 SOCKS5 proxy 比對網域。可以當指令列工具 srt 或函式庫(SandboxManager)給自己的 Harness 用,設定裡的 filesystem 和 network 欄位、空的 allowedDomains 等於不能連網;目前標成 research preview。
  13. OpenAI Codex|linux-sandbox README:Codex 在 Linux 上預設用 bubblewrap,整個檔案系統唯讀、工作目錄可寫、.git 和 .codex 重新掛回唯讀,舊的 Landlock 做法標成 legacy;指令列入口是 codex sandbox。
  14. E2B|infra:每個 sandbox 一台 Firecracker microVM。
  15. Docker|Sandboxes isolation:每個 sandbox 是有自己 kernel 的 microVM,container 則共用主機的 kernel。
  16. Docker|Sandboxes architecture:microVM 和 container 的隔離程度比較、microVM 換來隔離的代價是比較吃資源,以及 sandbox 裡只放假的憑證、由外面的 proxy 換成真的。
  17. OpenHands|Docker Sandbox:整個 Agent 服務跑在 container 裡,SANDBOX_VOLUMES 怎麼掛進主機路徑,掛成可寫的影響。
  18. Docker|Protect the Docker daemon socket:能對 Docker daemon 下指令可能帶來主機 root 權限的官方警告。
  19. OpenAI Codex|seatbelt_base_policy.sbpl:Codex 在 macOS 上的 Seatbelt 規則檔,從全部拒絕開始,再逐條打開。
  20. Cloudflare|Dynamic, identity-aware, and secure Sandbox auth:2026-04-13;sandbox 外的 proxy 替請求附上憑證,sandbox 裡的 Agent 拿不到真的憑證。
  21. OpenAI|Building a safe, effective sandbox to enable Codex on Windows:Codex Windows sandbox 的設計過程,第一版只靠環境變數擋網路被形容為「advisory」,後來改成專屬使用者帳號加防火牆規則。
  22. E2B|Security and compliance:每個 sandbox 是有自己 kernel 的 Firecracker microVM。
  23. Vercel|Sandbox:每個 sandbox 跑在有自己檔案系統和網路的 Firecracker microVM。
  24. Cloudflare|Sandbox SDK:每個 instance 是有自己 kernel 和網路的 microVM。
  25. Modal|Sandboxes:預設用 gVisor,也可以選有自己 kernel 的 VM。
  26. Kubernetes SIGs|Agent Sandbox:Kubernetes 上的 sandbox 編排,底層隔離交給 gVisor 或 Kata Containers。

上一篇
Day 20|寫在 Prompt 裡的規則,擋得住 Agent 嗎?
下一篇
Day 22|Agent 該用誰的身分做事?
系列文
AI Agent 上線要想清楚的事:30 天拆解 Harness 的設計取捨 共 24 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言